<script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/xlsx/0.18.2/xlsx.full.min.js"></script>
<script>
    // 将blob对象创建bloburl，然后用a标签实现弹出下载框
    function openDownloadDialog(blob, fileName) {
        if (typeof blob == "object" && blob instanceof Blob) {
            blob = URL.createObjectURL(blob); // 创建blob地址
        }
        var aLink = document.createElement("a");
        aLink.href = blob;
        // HTML5新增的属性，指定保存文件名，可以不要后缀，注意，有时候 file:///模式下不会生效
        aLink.download = fileName || "";
        var event;
        if (window.MouseEvent) event = new MouseEvent("click");
        //   移动端
        else {
            event = document.createEvent("MouseEvents");
            event.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        }
        aLink.dispatchEvent(event);
    }
</script>
<script>
    // 将workbook装化成blob对象
    function workbook2blob(workbook) {
        // 生成excel的配置项
        var wopts = {
            // 要生成的文件类型
            bookType: "xlsx",
            // // 是否生成Shared String Table，官方解释是，如果开启生成速度会下降，但在低版本IOS设备上有更好的兼容性
            bookSST: false,
            type: "binary"
        };
        var wbout = XLSX.write(workbook, wopts);
        // 将字符串转ArrayBuffer
        function s2ab(s) {
            var buf = new ArrayBuffer(s.length);
            var view = new Uint8Array(buf);
            for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
            return buf;
        }
        var blob = new Blob([s2ab(wbout)], {
            type: "application/octet-stream"
        });
        return blob;
    }

    // 用的例子
    var sheet1data = [
        ['商品库存动销报表'],
        [
            ...new Array(3).fill('商品信息'),
            ...new Array(6).fill('入库情况'),
            ...new Array(8).fill('出库情况'),
            '8.11期末总量',
            '8.11采购在途总数量',
            '当前锁库数量',
        ],
        [
            '品牌名称', '商品条码', '商品名称', '入库总量', '采购入库数量',
            ...new Array(3).fill('其它入库数量'),
            '出库总量',
            ...new Array(3).fill('销售出库数量'),
            ...new Array(3).fill('其它出库数量'),
            ...new Array(3).fill(''),
        ],

        [
            ...new Array(5).fill(''),
            '调拨入库数量', '退货入库数量', '其他入库数量', '库存盘盈数量',
            '出库总量',
            '批发出库数量', '代发出库数量', '电商出库数量',
            '市场出库数量', '调拨出库数量', '其他出库数量', '库存盘亏数量',
            ...new Array(3).fill(''),
        ],

    ];
    var sheet1 = XLSX.utils.aoa_to_sheet(sheet1data);
    sheet1['!merges'] = [
        // 第1行 横向合并
        { s: { r: 0, c: 0 }, e: { r: 0, c: 19 } },
        // 第2行 横向合并
        { s: { r: 1, c: 0 }, e: { r: 1, c: 2 } },
        { s: { r: 1, c: 3 }, e: { r: 1, c: 8 } },
        { s: { r: 1, c: 9 }, e: { r: 1, c: 16 } },
        // 第2行 纵向合并
        { s: { r: 1, c: 17 }, e: { r: 3, c: 17 } },
        { s: { r: 1, c: 18 }, e: { r: 3, c: 18 } },
        { s: { r: 1, c: 19 }, e: { r: 3, c: 19 } },
        // 第3行 纵向合并
        { s: { r: 2, c: 0 }, e: { r: 3, c: 0 } },
        { s: { r: 2, c: 1 }, e: { r: 3, c: 1 } },
        { s: { r: 2, c: 2 }, e: { r: 3, c: 2 } },
        { s: { r: 2, c: 3 }, e: { r: 3, c: 3 } },
        { s: { r: 2, c: 4 }, e: { r: 3, c: 4 } },
        // 第3行 横向合并
        { s: { r: 2, c: 5 }, e: { r: 2, c: 8 } },
        // 第3行 纵向合并
        { s: { r: 2, c: 9 }, e: { r: 3, c: 9 } },
        // 第3行 横向合并
        { s: { r: 2, c: 10 }, e: { r: 2, c: 12 } },
        { s: { r: 2, c: 13 }, e: { r: 2, c: 16 } },
    ]

    // let sheet2data = [{ name: "张三", do: "整理文件" }, { name: "李四", do: "打印" }];
    // let sheet3data = [{ name: "张大人", do: "vue" }, { name: "李大人", do: "react" }];
    // var sheet2 = XLSX.utils.json_to_sheet(sheet2data);
    // var sheet3 = XLSX.utils.json_to_sheet(sheet3data);

    /* create a new blank workbook */
    var wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, sheet1, "部门统计");
    // XLSX.utils.book_append_sheet(wb, sheet2, "行政部");
    // XLSX.utils.book_append_sheet(wb, sheet3, "前端部");
    const workbookBlob = workbook2blob(wb);
    openDownloadDialog(workbookBlob, `部门统计.xlsx`);

    // let sheet1data = [
    //     ['商品库存动销报表'],
    //     ['商品信息', '入库情况', '出库情况', '8.11期末总量', '8.11采购在途总数量', '当前锁库数量'],
    // ];

    // const workSheet = XLSX.utils.json_to_sheet(sheet1data);
    // const workbook = XLSX.utils.book_new();
    // // 设置工作表的记录范围
    // // [列号][行号]，A1 则代表 A 列的第1行
    // // 列数一般是已知的（未知时可以设置为ZZ）
    // // 行数则以 xlsxData 内容的长度结束即可
    // workSheet['!ref'] = `A1:AI${sheet1data.length}`;
    // // s 意为 start ，即开始的单元格
    // // r 是 row ，表示行号，从 0 计起
    // // c 是 col ，表示列号，从 0 计起
    // const merge = [
    //     // 横向合并，范围是第1行的列0到列19
    //     { s: { r: 0, c: 0 }, e: { r: 0, c: 19 } },
    //     { s: { r: 1, c: 1 }, e: { r: 1, c: 2 } },
    //     { s: { r: 1, c: 3 }, e: { r: 1, c: 8 } },

    //     // // 纵向合并，范围是第1列的行1到行2
    //     // { s: { r: 0, c: 0 }, e: { r: 1, c: 0 } },
    //     // // 纵向合并，范围是第2列的行1到行2
    //     // { s: { r: 0, c: 1 }, e: { r: 1, c: 1 } },
    //     // // 横向合并，范围是第1行的列3到列5
    //     // { s: { r: 0, c: 2 }, e: { r: 0, c: 4 } },
    //     // // 横向合并，范围是第1行的列6到列11
    //     // { s: { r: 0, c: 5 }, e: { r: 0, c: 10 } },
    //     // // 横向合并，范围是第1行的列12到列17
    //     // { s: { r: 0, c: 11 }, e: { r: 0, c: 16 } },
    //     // // 横向合并，范围是第1行的列18到列23
    //     // { s: { r: 0, c: 17 }, e: { r: 0, c: 22 } },
    //     // // 横向合并，范围是第1行的列24到列29
    //     // { s: { r: 0, c: 23 }, e: { r: 0, c: 28 } },
    //     // // 横向合并，范围是第1行的列30到列35
    //     // { s: { r: 0, c: 29 }, e: { r: 0, c: 34 } }
    // ];
    // workSheet['!merges'] = merge;
    // // sheet0 是工作表的名称
    // XLSX.utils.book_append_sheet(workbook, workSheet, 'sheet0');
    // // 执行数据转换文件写入
    // XLSX.writeFileSync(workbook, '文档名称', {
    //     bookType: 'xlsx',
    //     bookSST: true,
    //     type: 'array'
    // });
    // const workbookBlob = workbook2blob(workbook);
    // openDownloadDialog(workbookBlob, `部门统计.xlsx`);










</script>